package org.atlantis.datasink.server;

import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

import org.atlantis.datasink.DeviceData;
import org.atlantis.datasink.event.EventManager;
import org.atlantis.datasink.event.EventQueue;
import org.atlantis.datasink.utils.InternalEventNames;

public class ServerManager {

	private static class Holder {
		static ServerManager serverManager = new ServerManager();
	}

	public static ServerManager getInstance() {
		return Holder.serverManager;
	}

	private Map<String, Set<Long>> deviceCache = new HashMap<String, Set<Long>>();
	private ReadWriteLock rwLock = new ReentrantReadWriteLock();
	private EventQueue disconnectQueue = EventManager.getInstance().getOrCreate(InternalEventNames.DEVICE_DISCONNECT);

	public boolean contain(String id, long deviceId) {
		rwLock.readLock().lock();
		try {
			Set<Long> deviceIds = deviceCache.get(id);
			if (deviceIds == null || deviceIds.isEmpty()) return false;
			return deviceIds.contains(deviceId);
		} finally {
			rwLock.readLock().unlock();
		}
	}

	public void disconnect(String id) {
		rwLock.writeLock().lock();
		try {
			Set<Long> deviceIds = deviceCache.remove(id);
			if (deviceIds == null || deviceIds.isEmpty()) return;
			disconnectQueue.offer(deviceIds);
		} finally {
			rwLock.writeLock().unlock();
		}
	}

	public void connectIfAbsent(String id, List<DeviceData> datas) {
		rwLock.writeLock().lock();
		try {
			Set<Long> deviceIds = deviceCache.get(id);
			if (deviceIds == null) {
				deviceIds = new HashSet<Long>();
				deviceCache.put(id, deviceIds);
			}
			
		} finally {
			rwLock.writeLock().unlock();
		}
	}
}
